<template>
  <el-popover popper-class="no-padding-pop" :width="popWidth" v-model:visible="visible" @show="handleShow()">
    <template #reference>
      <i class="bs-icon-set" :style="referStyle" :class="referClass"></i>
    </template>
    <div class="check-list-wrap" :style="{height: containerHeight + 'px'}">
      <el-scrollbar>
        <ul class="check-list" ref="listRef">
          <li class="check-item">
            <el-checkbox @change="handleChangeAll" :indeterminate="isIndeterminate" v-model="checkAll">全部</el-checkbox>
          </li>
          <draggable
            :list="list"
            animation="500"
            item-key="__index"
            @end="handleDragEnd"
          >
            <template #item="{element}">
              <li class="check-item">
                <div class="checkbox-wrap">
                  <el-checkbox @change="handleChangeItem" :disabled="element._disabled" v-model="element._checked">{{ element.label || element.prop || element.type}}</el-checkbox>
                </div>
                <div class="icon">
                  <i class="bs-icon-menu"></i>
                </div>
              </li>
            </template>
          </draggable>
        </ul>
      </el-scrollbar>
    </div>
  </el-popover>
</template>
<script lang="ts" setup>
import {ref, watch, nextTick} from 'vue'
import draggable from 'vuedraggable'
import BsTable from './BsTable.vue'

type BsTableCtrlProps = {
  popWidth?: string | number
  referStyle?: string
  referClass?: string
  tableRef?: InstanceType<typeof BsTable>
}

const props = withDefaults(defineProps<BsTableCtrlProps>(), {
  popWidth: 200
})

const containerHeight = ref(0)
const list = ref<ColumnItem[]>([])
const checkAll = ref(false)
const isIndeterminate = ref(false)
const visible = ref(false)

const listRef = ref<HTMLDivElement | undefined>()

/**
 * 初始化列表值
 */
const initList = () => {
  if (props.tableRef) {
    list.value = props.tableRef.getAllColumns()
    initCheckAllValue()
    checkAllStatus()
  }
}

/**
 * 初始化全选值
 */
const initCheckAllValue = () => {
  if (list.value.every(el => el._checked)) {
    checkAll.value = true
  } else if (list.value.every(el => !el._checked)) {
    checkAll.value = false
  }
}

/**
 * 初始化列表区域宽度及高度
 * // TODO：目前只实现高度自动化设定
 */
const initListStyle = () => {
  nextTick(() => {
    if (listRef.value) {
      const height = listRef.value.offsetHeight
      const inHeight = window.innerHeight - 200
      if (height > inHeight) {
        containerHeight.value = inHeight
      } else {
        containerHeight.value = height
      }
    }
  })
}

/**
 * 全选选择状态设定
 */
const checkAllStatus = () => {
  const arr = list.value.filter(el => el._checked)
  isIndeterminate.value = !!(arr.length && arr.length !== list.value.length)
}

const handleShow = () => {
  initListStyle()
}

const handleChangeAll = (val: any) => {
  list.value.forEach(el => {
    if (!el._disabled) {
      el._checked = val
    }
  })
  checkAllStatus()
}

const handleChangeItem = () => {
  initCheckAllValue()
  checkAllStatus()
}
/**
 * 拖拽结束
 */
const handleDragEnd = () => {}

initList()
watch(() => props.tableRef && props.tableRef.columns, () => {
  initList()
})
</script>
<style lang="scss" scoped>
.bs-icon-set {
  font-size: 18px;
  color: #8C8F9E;
}
.check-list-wrap {
  height: 100px;
}
.check-list {
  padding: 0 10px;
  .check-item {
    display: flex;
    align-items: center;
    .checkbox-wrap {
      flex: 1;
    }
  }
}
</style>
